//@ts-nocheck
import { ExportData, AdditionData } from './interface'

//  eslint-disable-next-line
CanvasRenderingContext2D.prototype.wrapText = function (text, x, y, maxWidth, lineHeight) {
  if (typeof text !== 'string' || typeof x !== 'number' || typeof y !== 'number') {
    return
  }

  // eslint-disable-next-line @typescript-eslint/no-this-alias
  let context = this
  let canvas = context.canvas

  if (typeof maxWidth === 'undefined') {
    maxWidth = canvas?.width || 300
  }
  if (typeof lineHeight === 'undefined') {
    lineHeight =
      (canvas && parseInt(window.getComputedStyle(canvas).lineHeight)) ||
      parseInt(window.getComputedStyle(document.body).lineHeight)
  }

  // 字符分隔为数组
  let arrText = text.split('')
  let line = ''

  // 如果需要换行, 调整垂直居中坐标(此处只针对两行做了简单处理, 多行之后根据需求维护)
  let initMetrics = context.measureText(text)
  let initWidth = initMetrics.width
  if (initWidth > maxWidth) y -= lineHeight / 2

  for (let n = 0; n < arrText.length; n++) {
    let testLine = line + arrText[n]
    let metrics = context.measureText(testLine)
    let testWidth = metrics.width
    if (testWidth > maxWidth && n > 0) {
      context.fillText(line, x, y)
      line = arrText[n]
      y += lineHeight
    } else {
      line = testLine
    }
  }
  context.fillText(line, x, y)
  return y
}

/** 该方法用来绘制一个有填充色的圆角矩形
 *@param cxt:canvas的上下文环境
 *@param x:左上角x轴坐标
 *@param y:左上角y轴坐标
 *@param width:矩形的宽度
 *@param height:矩形的高度
 *@param radius:圆的半径
 *@param fillColor:填充颜色
 **/
// eslint-disable-next-line max-params
function fillRoundRect(cxt, x, y, width, height, radius, /* optional */ fillColor) {
  // 圆的直径必然要小于矩形的宽高
  if (2 * radius > width || 2 * radius > height) {
    return false
  }

  cxt.save()
  cxt.translate(x, y)
  // 绘制圆角矩形的各个边
  drawRoundRectPath(cxt, width, height, radius)
  cxt.fillStyle = fillColor || '#000' // 若是给定了值就用给定的值否则给予默认值
  cxt.fill()
  cxt.restore()
}
/** 该方法用来绘制圆角矩形
 *@param cxt:canvas的上下文环境
 *@param x:左上角x轴坐标
 *@param y:左上角y轴坐标
 *@param width:矩形的宽度
 *@param height:矩形的高度
 *@param radius:圆的半径
 *@param lineWidth:线条粗细
 *@param strokeColor:线条颜色
 **/
// eslint-disable-next-line max-params
function strokeRoundRect(
  cxt,
  x,
  y,
  width,
  height,
  radius,
  /* optional */ lineWidth,
  /* optional */ strokeColor
) {
  // 圆的直径必然要小于矩形的宽高
  if (2 * radius > width || 2 * radius > height) {
    return false
  }

  cxt.save()
  cxt.translate(x, y)
  // 绘制圆角矩形的各个边
  drawRoundRectPath(cxt, width, height, radius)
  cxt.lineWidth = lineWidth || 2 // 若是给定了值就用给定的值否则给予默认值2
  cxt.strokeStyle = strokeColor || '#000'
  cxt.stroke()
  cxt.restore()
}

// eslint-disable-next-line max-params
function drawRoundRectPath(cxt, width, height, radius) {
  cxt.beginPath(0)
  // 从右下角顺时针绘制，弧度从0到1/2PI
  cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2)

  // 矩形下边线
  cxt.lineTo(radius, height)

  // 左下角圆弧，弧度从1/2PI到PI
  cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI)

  // 矩形左边线
  cxt.lineTo(0, radius)

  // 左上角圆弧，弧度从PI到3/2PI
  cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2)

  // 上边线
  cxt.lineTo(width - radius, 0)

  // 右上角圆弧
  cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2)

  // 右边线
  cxt.lineTo(width, height - radius)
  cxt.closePath()
}

function drawBackground(context: CanvasRenderingContext2D, width: number, height: number) {
  context.fillStyle = 'white'
  context.fillRect(0, 0, width, height)
}

function drawTypeName(context: CanvasRenderingContext2D, typeName: string) {
  context.fillStyle = '#3F60FC'
  context.font = 'normal bold 22px MicrosoftYahei'
  context.wrapText(typeName, 24, 60, 800, 33)
}

function drawStem(context: CanvasRenderingContext2D, stem: string): number {
  context.fillStyle = '#07132B'
  context.font = 'normal bold 22px MicrosoftYahei'
  return context.wrapText(stem, 120, 60, 800 - 24 - 100, 33)
}

function drawSubmitCount(
  context: CanvasRenderingContext2D,
  y: number,
  submitCount: string
): number {
  context.fillStyle = '#A6B1BF'
  context.font = 'normal 400 22px MicrosoftYahei'
  return context.wrapText(submitCount, 24, y, 300, 33)
}

export function saveImage(imgSrc: string) {
  const saveLink = document.createElement('a')
  saveLink.href = imgSrc
  saveLink.download = 'statistics_image.png'
  saveLink.click()
}

export const exportImage = async (
  imgSrc: string,
  data: ExportData,
  additionData?: AdditionData
) => {
  const exportCanvas = document.createElement('canvas')
  const context: CanvasRenderingContext2D = exportCanvas.getContext('2d')
  const canvasWidth = 800
  exportCanvas.width = canvasWidth

  /** 绘制题干 */
  let stemYCoo: number = drawStem(context, data.stem)
  let yCoo = stemYCoo + 33 // 加上当前的行高

  /** 绘制提交人数 */
  yCoo = drawSubmitCount(context, yCoo + 12, `提交人数：${data.submitCount}人`)
  yCoo = yCoo + 33 // 加上当前的行高

  /** 绘制图片 */
  const chartImg = await getImageInfo(imgSrc)

  const imgWidth = chartImg.width
  const imgHeight = chartImg.height

  const drawImgWidth = canvasWidth
  const drawImgHeight = (drawImgWidth * imgHeight) / imgWidth

  exportCanvas.height = yCoo + 32 + drawImgHeight + 60

  let _additionImage: HTMLImageElement = null
  let _additionDrawImgWidth = null
  let _additionDrawImgHeight = null

  if (additionData) {
    let _chartLabelHeight: number = 32 + 36
    _additionImage = await getImageInfo(additionData.image)
    _additionDrawImgWidth = canvasWidth
    _additionDrawImgHeight = (drawImgWidth * _additionImage.height) / _additionImage.width
    exportCanvas.height = yCoo + 32 + drawImgHeight + _chartLabelHeight + 32 + drawImgHeight + 60
  }

  /** 绘制背景 */
  drawBackground(context, canvasWidth, exportCanvas.height)

  /** 绘制题型文字 */
  drawTypeName(context, data.typeName)

  !data.hideSubmitCount &&
    drawSubmitCount(context, stemYCoo + 33 + 12, `提交人数：${data.submitCount}人`)

  drawStem(context, data.stem)

  context.drawImage(chartImg, 0, yCoo + 32, drawImgWidth, drawImgHeight)

  /** 附加的信息 */
  if (additionData) {
    yCoo += drawImgHeight
    yCoo += 32
    strokeRoundRect(context, 24, yCoo, 92, 36, 2, 2, '#F0F3F7')
    context.fillStyle = '#3F60FC'
    context.font = 'normal bold 16px MicrosoftYahei'
    context.textAlign = 'center'
    context.fillText(additionData.typeName, 70, yCoo + 24)

    yCoo += 36
    context.drawImage(_additionImage, 0, yCoo + 32, _additionDrawImgWidth, _additionDrawImgHeight)
  }

  const dataURL = exportCanvas.toDataURL('image/png')
  saveImage(dataURL)
}

const getImageInfo = (imgSrc: string): Promise<HTMLImageElement> => {
  const chartImg: HTMLImageElement = new Image()
  chartImg.src = imgSrc
  return new Promise((reslove, reject) => {
    chartImg.onload = () => {
      reslove(chartImg)
    }
  })
}

export const getPercentChartDataUrl = (options: Array<any>, total: number) => {
  const exportCanvas = document.createElement('canvas')
  const context: CanvasRenderingContext2D = exportCanvas.getContext('2d')
  const canvasWidth = 800
  const canvasHeight = options.length * 43 + 64

  exportCanvas.width = canvasWidth
  exportCanvas.height = canvasHeight

  /** 绘制背景 */
  drawBackground(context, canvasWidth, canvasHeight)

  let textMaxWidth = 0
  context.font = 'normal bold 22px MicrosoftYahei'

  options.forEach((option) => {
    const _textWidth: number = context.measureText(option.choiceContent).width
    if (_textWidth > textMaxWidth) {
      textMaxWidth = _textWidth
    }
  })

  let _yCoo = 32
  options.forEach((option, optionIndex) => {
    context.fillStyle = '#07132B'
    context.font = 'normal bold 22px MicrosoftYahei'
    context.fillText(option.choiceContent, 24, _yCoo + 5)

    fillRoundRect(context, textMaxWidth + 24 + 24, _yCoo - 8, 122, 12, 6, 'rgba(52,59,94,.09)')
    const _percent = Math.round((option.choiceCount / total) * 10000) / 100
    fillRoundRect(
      context,
      textMaxWidth + 24 + 24,
      _yCoo - 8,
      (122 * _percent) / 100,
      12,
      6,
      '#3F60FC'
    )
    context.fillStyle = '#3F60FC'
    context.font = 'normal 400 22px MicrosoftYahei'
    context.fillText(_percent + '%', textMaxWidth + 24 + 24 + 122 + 16, _yCoo + 5)
    context.fillText(`${option.choiceCount}人已选`, textMaxWidth + 24 + 24 + 122 + 79, _yCoo + 5)
    _yCoo += 38
  })

  const canvasImage = exportCanvas.toDataURL('image/png')
  return canvasImage
}

export const statisticHeatMapCanvas = async () => {
  const exportCanvas = document.createElement('canvas')
  const context: CanvasRenderingContext2D = exportCanvas.getContext('2d')
  const canvasWidth = 800
  // const itemWidth
}
